home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 June: Reference Library / Dev.CD Jun 96 RL / Dev.CD Jun 96 RL.toast / Technical Documentation / develop / develop Issue 23 / develop Issue 23 code / ProjectDrag 1.1b8 / Sources / ProjectDrag Sources / ExternalCheckIn.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-24  |  6.6 KB  |  273 lines  |  [TEXT/MPS ]

  1. /* ExternalCheckIn.c: External CheckIn applet for ProjectDrag
  2.  *
  3.  * A set of applets for drag and drop source control by Tim Maroney.
  4.  * See develop, issue 23 for details.
  5.  *
  6.  * Built on DropShell by Leonard Rosenthol, Stephan Somogyi, and Marshall Clow,
  7.  * and using the MoreFiles utilities by Jim Luther.
  8.  *
  9.  * This software is free, but don't modify and redistribute it without
  10.  * changing the status window to indicate your name and your changes!
  11.  */
  12.  
  13.  
  14. #include <Errors.h>
  15. #include <StandardFile.h>
  16.  
  17. #include "DSUserProcs.h"
  18. #include "SourceServer.h"
  19. #include "PDUtilities.h"
  20. #include "PDDialogs.h"
  21. #include "Comments.h"
  22. #include "FileCancel.h"
  23. #include "TasksAndErrors.h"
  24. #include "FileCopy.h"
  25.  
  26.  
  27. void ExternalCheckInFile(FSSpec *file);
  28.  
  29.  
  30. /* This routine is called for each file passed in the ODOC event. */
  31.  
  32. pascal void OpenDoc ( FSSpecPtr myFSSPtr, Boolean opening, Handle userDataHandle )
  33. {
  34. #pragma unused ( opening )
  35. #pragma unused ( userDataHandle )
  36.  
  37.     ExternalCheckInFile(myFSSPtr);
  38. }
  39.  
  40.  
  41.  
  42. /* filter files based on (file NOT original) AND (file.name IS original.name) */
  43.  
  44. pascal Boolean FindTargetFileFilter(CInfoPBPtr pb, Ptr myDataPtr)
  45. {
  46.     FSSpecPtr theFile = (FSSpecPtr)myDataPtr;
  47.     Boolean display = false;
  48.     /* XXX make sure it has a CKID */
  49.     if (pb->hFileInfo.ioVRefNum != theFile->vRefNum
  50.         || pb->hFileInfo.ioFlParID != theFile->parID)
  51.         display = EqualString(theFile->name, pb->hFileInfo.ioNamePtr, false, false);
  52.     return !display;
  53. }
  54.  
  55.  
  56. void ExternalCheckInFile(FSSpec *file)
  57. {
  58.     Str63 userName;
  59.     Str15 nickname;
  60.     Str255 comment;
  61.     AEDesc command;
  62.     Str255 projectName;
  63.     OSErr err;
  64.     CKIDHandle theCKID;
  65.     FSSpec targetFile;
  66.     FSSpec targetFolder;
  67.         
  68.     TaskStart(2001, 1, file->name, NULL, NULL, NULL); /* checking in */
  69.     
  70.     /* find the user name and initials */
  71.     err = GetUserSettings(userName, nickname, false);
  72.     if (err != noErr)
  73.     {
  74.         gDone = true;
  75.         return;
  76.     }
  77.     
  78.     /* get the target file with Standard File */
  79.     {
  80.         StandardFileReply reply;
  81.         Str255 prompt;
  82.         Point where;
  83.         OSErr err;
  84.         FInfo info;
  85.         
  86.         /* must be the same type */
  87.         err = FSpGetFInfo(file, &info);
  88.         if (err != noErr)
  89.         {
  90.             RaiseErrorNumber(err);
  91.             return;
  92.         }
  93.         
  94.         SetPt(&where, -1, -1);
  95.         ReplaceInIndString(prompt, 2002, 1, file->name, NULL, NULL, NULL);
  96.         ParamText(prompt, NULL, NULL, NULL);
  97.         CustomGetFile (FindTargetFileFilter, 1, &info.fdType, &reply, kSelectWithPromptDialog, where,
  98.                         NULL, NULL, NULL, NULL, (Ptr)file);
  99.         if (!reply.sfGood)
  100.         {
  101.             RaiseErrorNumber(userCanceledErr);
  102.             return;
  103.         }
  104.         targetFile = reply.sfFile;
  105.     }
  106.  
  107.     /* get the CKID */
  108.     err = ExtractCKID(&targetFile, &theCKID);
  109.     if (err != noErr)
  110.     {
  111.         RaiseErrorNumber(err);
  112.         return;
  113.     }
  114.     
  115.     /* mount the project */
  116.     err = MountProjectFromCKID(theCKID, projectName);
  117.     if (err != noErr)
  118.     {
  119.         DisposeHandle((Handle)theCKID);
  120.         return;
  121.     }
  122.  
  123.     /* Make sure the file is writeable. */
  124.     if (!(*theCKID)->writeable && !(*theCKID)->modifyReadOnly)
  125.     {
  126.         /* check out the file */
  127.         TaskStart(2001, 2, file->name, NULL, NULL, NULL); /* checking out */
  128.     
  129.         /* create a CheckOut -m command for SourceServer
  130.          * CheckOut -m -cs <comment> -d <dir> -project <project> -u <user> <file>
  131.          */
  132.         err = CreateCommand(&command, "CheckOut");
  133.         if (err == noErr)
  134.             err = AddCStringArg(&command, "-m");
  135.         if (err == noErr)
  136.             err = AddCommentArg(&command, comment);
  137.         if (err == noErr)
  138.             err = AddDirArg(&command, targetFile.vRefNum, targetFile.parID);
  139.         if (err == noErr)
  140.             err = AddProjectArg(&command, projectName);
  141.         if (err == noErr)
  142.             err = AddUserArg(&command, userName);
  143.         if (err == noErr)
  144.             err = AddPStringArg(&command, targetFile.name);
  145.         if (err != noErr)
  146.         {
  147.             AEDisposeDesc(&command);
  148.             RaiseErrorNumber(err);
  149.             return;
  150.         }
  151.         
  152.         err = SendCommand(&command);        /* send the command to SourceServer */
  153.         if (err != noErr) return;
  154.         TaskDone();
  155.         
  156.         /* refetch the CKID */
  157.         DisposeHandle((Handle)theCKID);
  158.         theCKID = NULL;
  159.         err = ExtractCKID(&targetFile, &theCKID);
  160.         if (err != noErr)
  161.         {
  162.             RaiseErrorNumber(err);
  163.             return;
  164.         }
  165.     }
  166.     else
  167.     {
  168.         /* XXX -- ask about discarding changes */
  169.     }
  170.     
  171.     /* copy or move the external file in place of the target */
  172.     TaskStart(2001, 3, file->name, NULL, NULL, NULL); /* copying */
  173.     
  174.     /* XXX move the file to the trash instead of deleting it, and restore it
  175.      * to its place on error...
  176.      */
  177.     err = FSpDelete(&targetFile);
  178.     if (err != noErr) goto CancelCheckout;
  179.     
  180.     targetFolder = targetFile;
  181.     targetFolder.name[0] = 0;
  182.     err = FSpFileCopy(file, &targetFolder, NULL, NULL, 0, true);
  183.     if (err != noErr) goto CancelCheckout;
  184.     TaskDone();
  185.     
  186.     /* transfer the CKID into the (new) target file */
  187.     {
  188.         /* open the resource file */
  189.         CKIDHandle otherCKID;
  190.         short refNum = FSpOpenResFile(&targetFile, fsRdWrPerm);
  191.         if (refNum < 0) goto CancelCheckout;
  192.         
  193.         /* get the CKID from it and delete it (if any) */
  194.         otherCKID = (CKIDHandle) Get1IndResource('ckid', 1);
  195.         if (otherCKID != NULL)
  196.             RemoveResource((Handle)otherCKID);
  197.         
  198.         /* add the CKID */
  199.         otherCKID = theCKID;
  200.         err = HandToHand(&(Handle)otherCKID);
  201.         if (err != noErr)
  202.         {
  203.             CloseResFile(refNum);
  204.             goto CancelCheckout;
  205.         }
  206.         AddResource((Handle)otherCKID, 'ckid', 128, "\p");
  207.         err = ResError();
  208.         if (err != noErr)
  209.         {
  210.             DisposeHandle((Handle)otherCKID);
  211.             CloseResFile(refNum);
  212.             goto CancelCheckout;
  213.         }
  214.         
  215.         /* close the resource file */
  216.         CloseResFile(refNum);
  217.     }
  218.     
  219.     /* add the change comment to the file header */
  220.     comment[0] = 0;
  221.     err = AddCheckinComment(file, userName, nickname, comment);
  222.     if (err != noErr) goto CancelCheckout;
  223.     
  224.     /* create a CheckIn command for SourceServer
  225.      * CheckIn -cs <comment> -project <project> -u <user> <file>
  226.      */
  227.     err = CreateCommand(&command, "CheckIn");
  228.     if (err == noErr)
  229.         err = AddCommentArg(&command, comment);
  230.     if (err == noErr)
  231.         err = AddProjectArg(&command, projectName);
  232.     if (err == noErr)
  233.         err = AddUserArg(&command, userName);
  234.     if (err == noErr)
  235.         err = AddFileNameArg(&command, &targetFile);
  236.     if (err != noErr)
  237.     {
  238.         AEDisposeDesc(&command);
  239.         goto CancelCheckout;
  240.     }
  241.     
  242.     err = SendCommand(&command);        /* send the command to SourceServer */
  243.     if (err != noErr) goto CancelCheckout;
  244.     TaskDone();
  245.     return;
  246.  
  247. CancelCheckout:
  248.     /* pop the current task and start a new one if user confirms cancel */
  249.     if (!ResTextYesNo(kProjectDragStrings, kExternalCheckinFailedCancel,
  250.                      file->name, NULL, NULL, NULL))
  251.     {
  252.         DisposeHandle((Handle)theCKID);
  253.         RaiseErrorNumber(userCanceledErr);
  254.         return;
  255.     }
  256.     
  257.     TaskDone(); /* not really! */
  258.     TaskStart(2001, 4, targetFile.name, NULL, NULL, NULL); /* canceling */
  259.     err = FileCancel(&targetFile, theCKID);
  260.     DisposeHandle((Handle)theCKID);
  261.     if (err != noErr) return;
  262.     TaskDone();
  263. }
  264.  
  265.  
  266. void DoFileMenu(short itemID)
  267. {
  268.     if ( itemID == 1 )
  269.         SelectFile();        // call file selection userProc
  270.     else
  271.         SendQuitToSelf();    // send self a 'quit' event
  272. }
  273.